package com.selune.online.ordering.system.project.tenant.service;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import static com.selune.online.ordering.system.common.util.FindUserUtils.getTenantByTenantName;
import static com.selune.online.ordering.system.common.util.FindUserUtils.getTenantUserById;
import static com.selune.online.ordering.system.common.util.IdUtils.userGenId;
import com.selune.online.ordering.system.common.util.PasswordSaltUtils;
import com.selune.online.ordering.system.project.api.base.entity.TenantUserInfo;
import com.selune.online.ordering.system.project.api.base.exception.ParamsException;
import com.selune.online.ordering.system.project.api.base.exception.UserException;
import com.selune.online.ordering.system.project.api.base.response.Response;
import com.selune.online.ordering.system.project.api.mapper.TenantUserInfoMapper;
import com.selune.online.ordering.system.project.api.pojo.user.dto.LoginDTO;
import com.selune.online.ordering.system.project.api.pojo.user.tenant.dto.TenantLoginDTO;
import com.selune.online.ordering.system.project.api.pojo.user.tenant.dto.TenantUserInfoDTO;
import com.selune.online.ordering.system.project.api.pojo.user.tenant.vo.TenantUserInfoVO;
import com.selune.online.ordering.system.project.api.service.tenant.ITenantUserService;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 管理员信息管理Service
 *
 * @author xiaoyp
 * @date 2020/3/19
 */

@Service
@Slf4j
public class TenantUserServiceImpl implements ITenantUserService {
	
	@Resource
	private TenantUserInfoMapper tenantUserInfoMapper;
	
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Response<Boolean> saveTenantUser(TenantUserInfoDTO tenantUserInfoDTO) {
		if (null == tenantUserInfoDTO || StringUtils.isBlank(tenantUserInfoDTO.getTenantName())
				|| StringUtils.isBlank(tenantUserInfoDTO.getTenantPassword())
				|| null == tenantUserInfoDTO.getTenantPhone()) {
			log.error("ACCESS_LOG[]TenantUserServiceImpl[]saveTenantUser[]tenant user info params is null!");
			return Response.error("user.info.params.is.null");
		}
		Long userId = userGenId();
		TenantUserInfo tenantUserInfo = new TenantUserInfo();
		
		/* 加盐 */
		ByteSource salt = ByteSource.Util.bytes(userId.toString());
		String saltPassword = PasswordSaltUtils.salt(tenantUserInfoDTO.getTenantPassword(), salt);
		
		BeanUtils.copyProperties(tenantUserInfoDTO, tenantUserInfo);
		
		tenantUserInfo.setId(userId);
		tenantUserInfo.setTenantId(userId);
		tenantUserInfo.setTenantPassword(saltPassword);
		tenantUserInfo.setPasswordSalt(salt.toHex());
		
		int result = tenantUserInfoMapper.insert(tenantUserInfo);
		if (result == 1) {
			return Response.success("商户注册成功!", Boolean.TRUE);
		} else {
			return Response.error("商户注册失败");
		}
	}
	
	@Override
	public Response<TenantUserInfoVO> getTenantUser(Long userId) {
		
		if (null == userId) {
			log.error("ACCESS_LOG[]TenantUserServiceImpl[]getTenantUser[]tenant id is null!");
			return Response.error("用户id为空");
		}
		
		TenantUserInfo tenantUserInfo = tenantUserInfoMapper.selectById(userId);
		TenantUserInfoVO tenantUserInfoVO = new TenantUserInfoVO();
		BeanUtils.copyProperties(tenantUserInfo, tenantUserInfoVO);
		return Response.success(tenantUserInfoVO);
	}
	
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Response<Boolean> updateTenantUser(Long tenantId, TenantUserInfoDTO tenantUserInfoDTO) {
		getTenantUserById(tenantUserInfoMapper, tenantId);
		
		tenantUserInfoMapper.update(
			null,
			Wrappers.<TenantUserInfo>lambdaUpdate()
				.set(StringUtils.isNotBlank(tenantUserInfoDTO.getTenantName()), TenantUserInfo::getTenantName,
					tenantUserInfoDTO.getTenantName())
				.set(null != tenantUserInfoDTO.getTenantPhone(),TenantUserInfo::getTenantPhone,
					tenantUserInfoDTO.getTenantPhone())
				.set(StringUtils.isNotBlank(tenantUserInfoDTO.getTenantAddress()), TenantUserInfo::getTenantAddress,
					tenantUserInfoDTO.getTenantAddress())
				.eq((TenantUserInfo::getTenantId), tenantId));
		log.info("ACCESS_LOG[]TenantUserServiceImpl[]updateTenantUser[]update tenant info success!");
		return Response.success("更新信息成功!", Boolean.TRUE);
	}
	
	@Override
	public Response<TenantUserInfoVO> userLogin(LoginDTO loginDTO) {
		String userName = loginDTO.getUserName();
		String userPassword = loginDTO.getUserPassword();
		
		if (StringUtils.isBlank(userName) || StringUtils.isBlank(userPassword)) {
			log.error("ACCESS_LOG[]TenantUserServiceImpl[]userLogin[]tenant name or password is null!");
			throw new ParamsException("tenant.params.is.null");
		}
		
		TenantUserInfo tenantUserInfo = getTenantByTenantName(tenantUserInfoMapper, userName).getData();
		if (null == tenantUserInfo) {
			return Response.error("用户不存在");
		}
		ByteSource salt = ByteSource.Util.bytes(tenantUserInfo.getTenantId().toString());
		String password = tenantUserInfo.getTenantPassword();
		
		String salePassword = PasswordSaltUtils.salt(userPassword, salt);
		
		if (!salePassword.equals(password)) {
			return Response.error("密码错误");
		}
		
		TenantUserInfoVO tenantUserInfoVO = new TenantUserInfoVO();
		BeanUtils.copyProperties(tenantUserInfo, tenantUserInfoVO);
		
		log.info("ACCESS_LOG[]TenantUserServiceImpl[]userLogin[]tenant login success!");
		return Response.success(tenantUserInfoVO);
	}
	
	@Override
	public Response<Boolean> updateTenantLogin(Long tenantId, TenantLoginDTO loginDTO) {
		TenantUserInfo tenantUserInfo = getTenantUserById(tenantUserInfoMapper, tenantId).getData();
		String userName = loginDTO.getTenantName();
		String password = loginDTO.getTenantPassword();
		
		if (StringUtils.isBlank(password)) {
			log.error("ACCESS_LOG[]TenantUserServiceImpl[]updateTenantLogin[]tenant name or password is null!");
			throw new ParamsException("tenant.params.is.null");
		}
		
		ByteSource salt = ByteSource.Util.bytes(tenantId.toString());
		String newPassword = PasswordSaltUtils.salt(password, salt);
		int result = tenantUserInfoMapper.update(
			null,
			Wrappers.<TenantUserInfo>lambdaUpdate()
				.eq(TenantUserInfo::getTenantId, tenantId)
				.set(TenantUserInfo::getTenantPassword, newPassword)
		);
		if (result == 1) {
			return Response.success("更新密码成功!", Boolean.TRUE);
		} else {
			throw new UserException("更新密码失败");
		}
	}
	
}
